package server;

import util.Connection;

import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Vector;
import java.util.concurrent.ConcurrentLinkedQueue;


public class WatchdogThread implements Runnable {

	private Collection<Connection> connections;
	private Collection<Connection> beingHandled;
	private ConcurrentLinkedQueue<Connection> readThreadQueue;
	private ConcurrentLinkedQueue<MessageInfo> sendThreadQueue;
	
	public WatchdogThread(Vector<Connection> connections){
		this.connections = connections;
		this.beingHandled = new LinkedList<Connection>();
		this.readThreadQueue = new ConcurrentLinkedQueue<Connection>();
		this.sendThreadQueue = new ConcurrentLinkedQueue<MessageInfo>();
		
		for(int i = 0; i<4; i++){
			ReadThread readthread = new ReadThread(readThreadQueue, sendThreadQueue, connections, beingHandled);
			SendThread sendthread = new SendThread(sendThreadQueue, connections);
			
			Thread readthreadobj = new Thread(readthread);
			Thread sendthreadobj = new Thread(sendthread);
			readthreadobj.start();
			sendthreadobj.start();
		}
	}
	
	@Override
	public void run() {
		while(true){
			synchronized(connections){
				Collection<Connection> toRemove = new Vector<Connection>();
				for(Connection conn : connections){
					try {
						if(conn.getSocket().getInputStream().available() > 0 && !beingHandled.contains(conn)){
							
							readThreadQueue.add(conn);
							
							synchronized(beingHandled) {
								beingHandled.add(conn);
							}
							
							synchronized(readThreadQueue){
								readThreadQueue.notify();
							}
						}
					} catch (IOException e) {
						toRemove.add(conn);
					}
				}
				connections.removeAll(toRemove);
			}
		}
	}
}
